import { ref, watch, onMounted, onBeforeUnmount, nextTick, type Ref } from 'vue'

import * as echarts from 'echarts/core'
import { BarChart, LineChart, type BarSeriesOption, type LineSeriesOption } from 'echarts/charts'
import {
    TitleComponent,
    TooltipComponent,
    GridComponent,
    DatasetComponent,
    TransformComponent,
    LegendComponent,
    ToolboxComponent,
    type ToolboxComponentOption,
    type LegendComponentOption,
    type TitleComponentOption,
    type TooltipComponentOption,
    type GridComponentOption,
    type DatasetComponentOption
} from 'echarts/components'
import { LabelLayout, UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import type { ComposeOption, ECharts } from 'echarts/core'

// 类型组合
export type ECOption = ComposeOption<
    | BarSeriesOption
    | LineSeriesOption
    | TitleComponentOption
    | TooltipComponentOption
    | GridComponentOption
    | DatasetComponentOption
    | LegendComponentOption
    | ToolboxComponentOption
>

echarts.use([
    TitleComponent,
    TooltipComponent,
    LegendComponent,
    ToolboxComponent,
    GridComponent,
    DatasetComponent,
    TransformComponent,
    BarChart,
    LineChart,
    LabelLayout,
    UniversalTransition,
    CanvasRenderer
])

export function useEcharts(
    options: ECOption,
    theme: 'light' | 'dark' | Ref<'light' | 'dark'> = 'light',
    onEvents?: Record<string, (params: any) => void>
) {
    const chartRef = ref<HTMLDivElement | null>(null)
    let chartInstance: ECharts | null = null

    const initChart = () => {
        if (!chartRef.value) return
        const resolvedTheme = typeof theme === 'string' ? theme : theme.value
        chartInstance = echarts.init(chartRef.value, resolvedTheme)
        chartInstance.setOption(options)
        if (onEvents) {
            Object.entries(onEvents).forEach(([event, handler]) => {
                chartInstance!.on(event, handler)
            })
        }
        window.addEventListener('resize', resizeChart)
    }

    const disposeChart = () => {
        chartInstance?.dispose()
        chartInstance = null
        window.removeEventListener('resize', resizeChart)
    }

    const resizeChart = () => chartInstance?.resize()
    const updateOptions = (newOptions: ECOption) => chartInstance?.setOption(newOptions, true)
    const showLoading = () => chartInstance?.showLoading()
    const hideLoading = () => chartInstance?.hideLoading()

    // 监听主题变化
    if (typeof theme !== 'string') {
        watch(theme, () => {
            disposeChart()
            nextTick(() => initChart())
        })
    }

    onMounted(() => nextTick(initChart))
    onBeforeUnmount(() => disposeChart())

    return {
        chartRef,
        updateOptions,
        resizeChart,
        showLoading,
        hideLoading,
        chartInstance
    }
}
